﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

/**
 * Camera class.
 * This is a basic camera. It has transformation
 * functions to go between our two coordinate
 * spaces.
 */
public class Camera
{
    // Not truly making this a singleton, but will have a single static instance used for transformations,
    // and other functions dependant on the current camera.
    protected static Camera s_singleton;
    // Our position in worldCoordinates
    public static Vector3 s_position = new Vector3(0, 0, 0);

    /**
     * Camera's constructor.
     * Create's the camera.
     * @param position
     */
    public Camera(Vector3 position)
    {
        s_position = position;
        s_singleton = this;
    }

    /**
     * Camera's update function.
     * Takes a change in time in
     * milliseconds.
     * @param dt
     */
    virtual public void update(double dt)
    {
    }

    /**
     * Checks whether the given bounds are on screen.
     * @param topLeftCorner
     * @param bottomRightCorner
     */
    public static bool isOnScreen(Vector2 topLeftCorner, Vector2 bottomRightCorner)
    {
        if (bottomRightCorner.X < 0 ||
            bottomRightCorner.Y < 0 ||
            topLeftCorner.X > Game.kScreenWidth ||
            topLeftCorner.Y > Game.kScreenHeight)
        {
            return false;
        }
        return true;
    }
    /**
     * Checks whether the given bounds are on screen.
     * @param bounds
     */
    public static bool isOnScreen(Rectangle bounds)
    {
        return isOnScreen(new Vector2(bounds.Left, bounds.Top), new Vector2(bounds.Right, bounds.Bottom));
    }

    public static bool isNowOnScreen(Rectangle bounds)
    {
        if (bounds.Right < s_position.X ||
            bounds.Bottom < s_position.Y ||
            bounds.Left > s_position.X+Game.kScreenWidth ||
            bounds.Top > s_position.Y+Game.kScreenHeight)
        {
            return false;
        }
        return true;
    }

    /**
     * ScreenToWorld transformation.
     * Takes screenCoordiantes and converts
     * them into equivalent worldCoordinates
     * @param screenCoords
     */
    public static Vector3 screenToWorld(Vector3 screenCoords)
    {
        return new Vector3(s_position.X + screenCoords.X, s_position.Y + screenCoords.Y + .5f * screenCoords.Z, (screenCoords.Z * 2001f) - Priority.kNearestGameplay);
    }
    /**
     * ScreenToWorld transformation.
     * A version of the transformation that
     * assumes 0.0 as the z-depth.
     * @param screenCoords
     */
    public static Vector3 screenToWorld(Vector2 screenCoords)
    {
        return screenToWorld(new Vector3(screenCoords, 0.0f));
    }

    /**
     * WorldToScreen transformation.
     * Takes worldCoordinates and converts that into
     * the equivalent screenCoordinates.
     * @param worldCoords
     */
    public static Vector3 worldToScreen(Vector3 worldCoords)
    {
        return new Vector3(worldCoords.X - s_position.X, worldCoords.Y - s_position.Y - .5f * worldCoords.Z, (worldCoords.Z / 2001f) + Priority.kNearestGameplay);
    }
}
